from datetime import timedelta
from fastapi import APIRouter, Depends, HTTPException, status, File, UploadFile, Form, Request
from fastapi.security import OAuth2PasswordRequestForm
import os
import shutil
from uuid import uuid4

from app.core.config import settings
from app.core.security import create_access_token, verify_password, get_password_hash
from app.core.deps import get_current_active_user
from app.models.models import User, Role, UserRole
from app.schemas.user import Token, UserOut, UserLogin, ChangePassword, UserUpdate
from app.schemas.base import ResponseBase
from app.services.log_service import record_login_history

router = APIRouter()

@router.post("/login", response_model=ResponseBase[Token])
async def login_for_access_token(form_data: UserLogin, request: Request):
    """用户登录获取令牌"""
    # 获取客户端IP
    if "x-forwarded-for" in request.headers:
        ip_address = request.headers["x-forwarded-for"].split(",")[0]
    else:
        ip_address = request.client.host if request.client else "未知"
    
    # 获取用户代理
    user_agent = request.headers.get("user-agent", "未知")
    
    # 验证用户
    user = await User.filter(username=form_data.username).first()
    
    # 登录失败情况
    if not user:
        # 记录登录失败历史
        await record_login_history(
            user_id=0,
            username=form_data.username,
            ip_address=ip_address,
            user_agent=user_agent,
            login_status=False,
            login_message="用户不存在"
        )
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    if not verify_password(form_data.password, user.password):
        # 记录登录失败历史
        await record_login_history(
            user_id=user.id,
            username=user.username,
            ip_address=ip_address,
            user_agent=user_agent,
            login_status=False,
            login_message="密码错误"
        )
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    if not user.status:
        # 记录登录失败历史
        await record_login_history(
            user_id=user.id,
            username=user.username,
            ip_address=ip_address,
            user_agent=user_agent,
            login_status=False,
            login_message="用户已被禁用"
        )
        raise HTTPException(status_code=400, detail="用户已被禁用")
    
    # 登录成功，生成令牌
    access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        subject=user.username, expires_delta=access_token_expires
    )
    
    # 记录登录成功历史
    await record_login_history(
        user_id=user.id,
        username=user.username,
        ip_address=ip_address,
        user_agent=user_agent,
        login_status=True,
        login_message="登录成功"
    )
    
    return ResponseBase[Token](
        data=Token(access_token=access_token, token_type="bearer")
    )

@router.get("/me", response_model=ResponseBase[UserOut])
async def read_users_me(user: User = Depends(get_current_active_user)):
    """获取当前用户信息"""
    # 获取用户角色 - 通过关联表查询
    user_role_relations = await UserRole.filter(user_id=user.id).prefetch_related('role').all()
    roles = []
    for relation in user_role_relations:
        role = relation.role
        roles.append({
            "id": role.id,
            "name": role.name,
            "code": role.code
        })
    
    # 获取部门名称
    department_name = None
    if user.department_id:
        department = await user.department
        if department:
            department_name = department.name
    
    # 构建用户信息
    user_data = {
        "id": user.id,
        "username": user.username,
        "name": user.name,
        "email": user.email,
        "phone": user.phone,
        "avatar": user.avatar,
        "status": user.status,
        "department_id": user.department_id,
        "department_name": department_name,
        "roles": roles,
        "created_at": user.created_at,
        "updated_at": user.updated_at
    }
    
    return ResponseBase[UserOut](data=UserOut(**user_data))

@router.post("/change-password", response_model=ResponseBase)
async def change_password(
    password_data: ChangePassword,
    current_user: User = Depends(get_current_active_user)
):
    """修改密码"""
    # 验证旧密码
    if not verify_password(password_data.old_password, current_user.password):
        raise HTTPException(status_code=400, detail="旧密码不正确")
    
    # 验证新密码与确认密码是否一致
    if password_data.new_password != password_data.confirm_password:
        raise HTTPException(status_code=400, detail="新密码与确认密码不一致")
    
    # 更新密码
    hashed_password = get_password_hash(password_data.new_password)
    await User.filter(id=current_user.id).update(password=hashed_password)
    
    return ResponseBase(message="密码修改成功")

@router.put("/profile", response_model=ResponseBase)
async def update_user_profile(
    user_data: UserUpdate,
    current_user: User = Depends(get_current_active_user)
):
    """更新个人资料"""
    # 更新用户信息
    update_data = user_data.dict(exclude_unset=True)
    await User.filter(id=current_user.id).update(**update_data)
    
    return ResponseBase(message="个人资料更新成功")

@router.post("/avatar", response_model=ResponseBase)
async def upload_avatar(
    file: UploadFile = File(...),
    current_user: User = Depends(get_current_active_user)
):
    """上传头像"""
    # 创建上传目录
    upload_dir = os.path.join("static", "avatars")
    os.makedirs(upload_dir, exist_ok=True)
    
    # 生成文件名
    file_extension = os.path.splitext(file.filename)[1]
    file_name = f"{uuid4()}{file_extension}"
    file_path = os.path.join(upload_dir, file_name)
    
    # 保存文件
    with open(file_path, "wb") as buffer:
        shutil.copyfileobj(file.file, buffer)
    
    # 更新用户头像
    avatar_url = f"/static/avatars/{file_name}"
    await User.filter(id=current_user.id).update(avatar=avatar_url)
    
    return ResponseBase(data={"url": avatar_url}, message="头像上传成功")
